home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / METHOD1.ASM < prev    next >
Assembly Source File  |  1986-01-31  |  11KB  |  328 lines

  1.     PAGE    ,132
  2.     TITLE      Method 1
  3.     .286C      ; Tell MASM 2.0 about 286 instructions
  4. ;--------------------------------------------------------------:
  5. ;    Sample Program 1                       :
  6. ;                                   :
  7. ; This program switches into Protected Virtual Mode, changes   :
  8. ; the display attribute to reverse video, and returns to Real  :
  9. ; Mode to exit to DOS                           :
  10. ;                                   :
  11. ; Once entered into a file, do the following:               :
  12. ;    MASM SAMPLE1;                           :
  13. ;    LINK SAMPLE1;                           :
  14. ;    EXE2BIN SAMPLE1 SAMPLE1.COM                   :
  15. ;    DEL SAMPLE1.EXE                        :
  16. ;                                   :
  17. ; WARNING: This program will "kill" a PC.  I should only       :
  18. ; be run on an AT.                           :
  19. ;--------------------------------------------------------------:
  20.  
  21. bios_data_seg SEGMENT at 0040h
  22.           ORG    0067h
  23. io_rom_init   dw ?      ; dword variable in BIOS data segment
  24. - More (Y/N/NS)? ns
  25. io_rom_seg    dw ?      ;  used to store a dword address
  26. bios_data_seg ENDS
  27.  
  28. descriptor    STRUC
  29. seg_limit     dw 0      ; segment limit (1-65536 bytes)
  30. base_lo_word  dw 0      ; 24 bit physical address
  31. base_hi_byte  db 0      ; (0 - (16M-1))
  32. access_rights db 0      ; access rights byte
  33.           dw 0      ; reserved_386
  34. descriptor    ENDS
  35.  
  36. cmos_port    equ 070h
  37. code_seg_access equ 10011011b ;access rights byte for code seg
  38. data_seg_access equ 10010011b ;access rights byte for data seg
  39. disable_bit20    equ 11011101b ;8042 function code to de-gate A20
  40. enable_bit20    equ 11011111b ;8042 function code to gate A20
  41. inta01        equ 021h      ;8259 Int Controller #1
  42. intb01        equ 0A1h      ;8259 Int Controller #2
  43. port_a        equ 060h      ;8042 port A
  44. shut_cmd    equ 0FEh      ;cmd to 8042: shut down AT
  45. shut_down    equ 00Fh      ;CMOS shut down byte index
  46. status_port    equ 064h      ;8042 status port
  47. virtual_enable    equ 0001h     ;LSB=1: Protected Virtual Mode
  48.  
  49.     SUBTTL    Macro Definitions
  50.     PAGE
  51. ;--------------------------------------------------------------:
  52. ; These mnemonics are not supported in MASM 2.0 therefore      :
  53. ; they are supplied here as MACROS.                   :
  54. ;--------------------------------------------------------------:
  55. lgdt    MACRO       lgdt1      ;; Load Global Descriptor Table
  56.     LOCAL       lgdt2,lgdt3
  57.     db       00Fh
  58. lgdt2    label       byte
  59.     mov       dx,word ptr lgdt1
  60. lgdt3    label       byte
  61.     org       offset lgdt2
  62.     db       001h
  63.     org       offset lgdt3
  64.     ENDM
  65.  
  66. lmsw    MACRO       lmsw1      ;; Load Machine Status Word
  67.     LOCAL       lmsw2,lmsw3
  68.     db       00Fh
  69. lmsw2    label       byte
  70.     mov       si,ax
  71. lmsw3    label       byte
  72.     org       offset lmsw2
  73.     db       001h
  74.     org       offset lmsw3
  75.     ENDM
  76.  
  77.                   ;; This is a "hard coded" far jump
  78. jumpfar MACRO       jumpfar1,jumpfar2
  79.     db       0EAh
  80.     dw       (offset jumpfar1)
  81.     dw       jumpfar2
  82.     ENDM
  83.  
  84.     SUBTTL       Program entry point and data area
  85.     PAGE
  86. cseg    SEGMENT para       public     'code'
  87.     ASSUME    cs:cseg
  88.  
  89.     ORG    100h
  90. start:    jmp    short      main
  91.  
  92.     EVEN
  93. gdt    LABEL    word
  94.  
  95. gdt_desc    EQU  (($-gdt)/8)*8 + 0000000000000000b
  96. gdt1        descriptor    <gdt_leng,,,data_seg_access,>
  97. cs_code     EQU  (($-gdt)/8)*8 + 0000000000000000b
  98. gdt2        descriptor    <cseg_leng,,,code_seg_access,>
  99. cs_data     EQU  (($-gdt)/8)*8 + 0000000000000000b
  100. gdt3        descriptor    <cseg_leng,,,data_seg_access,>
  101. ss_desc     EQU  (($-gdt)/8)*8 + 0000000000000000b
  102. gdt4        descriptor    <0FFFFh,,,data_seg_access,>
  103. ds_desc     equ  (($-gdt)/8)*8 + 0000000000000000b
  104. gdt5        descriptor    <0FFFFh,,,data_seg_access,>
  105. es_desc     equ  (($-gdt)/8)*8 + 0000000000000000b
  106. gdt6        descriptor    <0FFFFh,,,data_seg_access,>
  107. gdt_leng    EQU  $-gdt
  108.         PAGE
  109. ;--------------------------------------------------------------:
  110. ; Format of the Segment Selector Component:               :
  111. ;                                   :
  112. ; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+           :
  113. ; |      INDEX              +TI+ RPL +           :
  114. ; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+           :
  115. ;                                   :
  116. ; TI = Table Indicator (0=GDT, 1=LDT)                   :
  117. ; RPL = Requested Privelege Level (00 = highest; 11 = Lowest)  :
  118. ;--------------------------------------------------------------:
  119. ; Format of the Global Descriptor Table                :
  120. ;            .-----------+             +---> TI  :
  121. ;            V        |             |++-> RPL :
  122. ;    GDT ==> +---------------+   |             |||       :
  123. ;        |   GDT_DESC    | --+    0000000000000000b      :
  124. ;        +---------------+                   :
  125. ;        |    CS_CODE    |    0000000000001000b      :
  126. ;        +---------------+                   :
  127. ;        |    CS_DATA    |    0000000000010000b      :
  128. ;        +---------------+                   :
  129. ;        |    SS_DESC    |    0000000000011000b      :
  130. ;        +---------------+                   :
  131. ;        |    DS_DESC    |    0000000000100000b      :
  132. ;        +---------------+                   :
  133. ;        |    ES_DESC    |    0000000000101000b      :
  134. ;        +---------------+                   :
  135. ;--------------------------------------------------------------:
  136.  
  137. i8259_1 db     ?       ; store for status of 8259 #1
  138. i8259_2 db     ?       ; store for status of 8259 #2
  139.  
  140.     SUBTTL Program Main
  141.     PAGE
  142. ;--------------------------------------------------------------:
  143. ; MAIN                                   :
  144. ;--------------------------------------------------------------:
  145.     ASSUME     ds:cseg
  146. main    PROC               ;ES=DS=CS
  147.     cld               ;forward
  148.  
  149.     mov     dx,cs           ;form 24bit address out of
  150.     mov     cx,offset gdt       ; CS:GDT
  151.     call     form_24bit_address
  152.     mov     gdt1.base_lo_word,dx  ;DESC now points to gdt
  153.     mov     gdt1.base_hi_byte,cl
  154.  
  155.     mov     dx,cs           ;form 24bit address out of
  156.     xor     cx,cx           ;  CS:0000
  157.     call     form_24bit_address
  158.     mov     gdt2.base_lo_word,dx  ;CS_CODE now points to
  159.     mov     gdt2.base_hi_byte,cl  ; CSEG as a code segment
  160.     mov     gdt3.base_lo_word,dx  ;CS_DATA now points to
  161.     mov     gdt3.base_hi_byte,cl  ; CSEG as a data segment
  162.  
  163.     mov     dx,ss           ;form 24bit address out of
  164.     xor     cx,cx           ; SS:0000
  165.     call     form_24bit_address
  166.     mov     gdt4.base_lo_word,dx  ;SS_DESC now points to
  167.     mov     gdt4.base_hi_byte,cl  ; stack segment
  168.  
  169.     lgdt     gdt           ;Load the GDTR
  170.  
  171.     mov     ah,enable_bit20   ;gate address bit 20 on
  172.     call     gate_a20
  173.     or     al,al           ; was the command accepted?
  174.     jz     m_10           ; go if yes
  175.     mov     dx,offset gate_failure  ;print error msg
  176.     mov     ah,9             ; and terminate
  177.     int     21h
  178.     int     20h
  179.  
  180. gate_failure     db   "Address line A20 failed to Gate open$"
  181.  
  182. m_10:    cli             ;No interrupts
  183.  
  184.     in     al,inta01   ;get status of Int Controller #1
  185.     mov     i8259_1,al
  186.     in     al,intb01   ;get status of Int Controller #2
  187.     mov     i8259_2,al
  188.  
  189.     ASSUME     ds:bios_data_seg
  190.     mov     dx,bios_data_seg  ;Real Mode Return address
  191.     mov     ds,dx
  192.     mov     io_rom_seg,cs
  193.     mov     io_rom_init,offset real
  194.  
  195.     mov     al,shut_down       ;Set shutdown byte
  196.     out     cmos_port,al       ; to shut down x05.
  197.     jmp     short    $+2       ;I/O delay
  198.     mov     al,5
  199.     out     cmos_port+1,al
  200.  
  201.     mov     ax,virtual_enable ;machine status word needed to
  202.     lmsw     ax           ;switch to virtual mode
  203.     jumpfar m_20,cs_code       ;Must purge prefetch queue
  204.  
  205. m_20:    ASSUME     ds:cseg       ;IN VIRTUAL MODE ...
  206.     mov     ax,ss_desc    ;stack segment selector
  207.     mov     ss,ax           ;user's ss+sp is not a descriptor
  208.  
  209.     mov     ax,cs_data
  210.     mov     ds,ax           ;DS = CSEG as data
  211.  
  212.     mov     gdt5.base_lo_word,0000h  ;use 8000 for COLOR
  213.     mov     gdt5.base_hi_byte,0Bh
  214.     mov     gdt6.base_lo_word,0000h
  215.     mov     gdt6.base_hi_byte,0Bh
  216.  
  217.     mov     ax,ds_desc
  218.     mov     ds,ax
  219.     mov     ax,es_desc
  220.     mov     es,ax
  221.     mov     cx,80*25
  222.     xor     si,si
  223.     xor     di,di
  224. m_30:    lodsw
  225.     mov     ah,70h     ;attribute reverse video
  226.     stosw
  227.     loop     m_30
  228.  
  229.     mov     al,shut_cmd    ;shutdown cmd
  230.     out     status_port,al ;get back into REAL mode
  231. m_40:    hlt
  232.     jmp     short m_40
  233.  
  234.     SUBTTL     Gate A20
  235.     PAGE
  236. ;--------------------------------------------------------------:
  237. ; GATE_A20                               :
  238. ; This routine controls a signal which gates address bit 20.   :
  239. ; The gate A20 signal is an output of the 8042 slave processor.:
  240. ; Address bit 20 should be gated on before entering protected  :
  241. ; mode.  It should be gated off after entering real mode from  :
  242. ; protected mode.                           :
  243. ; Input:  (AH)=0DDh addr bit 20 gated off (A20 always 0)       :
  244. ;      (AH)=0DFh addr bit 20 gated on  (286 controls A20)   :
  245. ; Output: (AL)=0 operation successful.    8042 has accepted cmd  :
  246. ;      (AL)=2 Failure -- 8042 unable to accept command.     :
  247. ;--------------------------------------------------------------:
  248. gate_a20  PROC
  249.     cli             ;disable ints while using 8042
  250.     call   empty_8042    ;insure 8042 input buffer empty
  251.     jnz    gate_a20_01   ;ret if 8042 unable to accept cmd
  252.     mov    al,0D1h         ;8042 command to write output port
  253.     out    status_port,al  ;output cmd to 8042
  254.     call   empty_8042      ;wait for 8042 to accept command
  255.     jnz    gate_a20_01   ;ret if 8042 unable to accept cmd
  256.     mov    al,ah         ;8042 port data
  257.     out    port_a,al     ;output port data to 8042
  258.     call   empty_8042    ;wait for 8042 to port data
  259. gate_a20_01:
  260.     ret
  261. gate_a20  ENDP
  262. ;--------------------------------------------------------------:
  263. ; EMPTY_8042                               :
  264. ; This routine waits for the 8042 buffer to empty           :
  265. ; Input:  None                               :
  266. ; Output: (AL)=0 8042 input buffer empty (ZF=1)            :
  267. ;      (AL)=2 Time out, 8042 buffer full (ZF=0)           :
  268. ;--------------------------------------------------------------:
  269. empty_8042  PROC
  270.     push   cx          ;save CX
  271.     sub    cx,cx          ;CX=0 will be the time out value
  272. empty_8042_01:
  273.     in     al,status_port ;read 8042 status port
  274.     and    al,00000010b   ;test input buffer full flag (D1)
  275.     loopnz empty_8042_01  ;loop until input buffer empty
  276.                   ; or time out
  277.     pop    cx          ;restore CX
  278.     ret
  279. empty_8042  ENDP
  280.  
  281.     SUBTTL form_24bit_address
  282.     PAGE
  283. ;--------------------------------------------------------------:
  284. ; FORM_24BIT_ADDRESS                           :
  285. ;    Input:  DX has some segment                   :
  286. ;         CX has some offset                    :
  287. ;    Output: DX has base_lo_word                   :
  288. ;         CL has base_hi_byte                   :
  289. ;--------------------------------------------------------------:
  290. form_24bit_address  PROC
  291.     push   ax
  292.          ;DX == s15 s14 s13 s12 s11 ... s04 s03 s02 s01 s00
  293.     rol    dx,4
  294.          ;DX == s11 ... s04 s03 s02 s01 s00 s15 s14 s13 s12
  295.     mov    ax,dx
  296.          ;AX == s11 ... s04 s03 s02 s01 s00 s15 s14 s13 s12
  297.     and    dl,0F0h
  298.          ;DX == s11 ... s04 s03 s02 s01 s00   0   0   0   0
  299.     and    ax,0Fh
  300.          ;AX ==   0 ...   0   0   0   0   0 s15 s14 s13 s12
  301.     add    dx,cx   ;form_24bit_address
  302.     mov    cx,ax   ;get base_hi_byte in CL
  303.     adc    cl,ch   ;carry in (CH=0)
  304.     pop    ax
  305.     ret
  306. form_24bit_address ENDP
  307.  
  308.     SUBTTL       Real Mode re-entry point.
  309.     PAGE
  310.     ASSUME ds:cseg           ;IN REAL MODE ...
  311.  
  312. real:    mov    dx,cs
  313.     mov    ds,dx           ;DS = CS
  314.     mov    ah,disable_bit20    ;gate address bit 20 on
  315.     call   gate_a20
  316.     mov    al,i8259_1
  317.     out    inta01,al       ;set status of Int Controller #1
  318.     mov    al,i8259_2
  319.     out    intb01,al       ;set status of Int Controller #2
  320.  
  321.     sti               ;turn the interrupts on
  322.     int    20h           ;back to DOS
  323.  
  324. main       ENDP
  325. cseg_leng  EQU $
  326. cseg       ENDS
  327.        END    start
  328.